<template>
	<div class="div-user-sum">
		<div class="div-top">
			<span>实验管理</span>
		</div>
		<span class="search_label">实验名称:</span>
		<el-input placeholder="请输入实验名称" v-model="vrResourceName" style="width:200px;margin-left: 10px" clearable/>
		<span class="search_label">所属专业:</span>
		<el-select v-model="majorId" placeholder="请选择专业" style="width:200px" clearable>
			<el-option v-for="item in majors" :key="item.id" :label="item.name" :value="item.id">
			</el-option>
		</el-select>
		<span class="search_label">实验模式:</span>
		<el-select v-model="mode" placeholder="请选择实验模式" style="width:200px" clearable>
			<el-option v-for="item in modes" :key="item.value" :label="item.label" :value="item.value">
			</el-option>
		</el-select>
		<el-button type="primary" style="margin:0 0 10px 10px" @click="currentChange(1)">搜索</el-button>
		<el-button type="primary" style="margin:0 0 10px 10px" @click="openAdd">添加实验</el-button>
		<div style="margin: 10px;">
			<el-table :data="tableDate" border>
				<el-table-column prop="cover" label="封面" width="140px" align='center'>
					<template slot-scope="scope">
						<el-image :src="baseurl+scope.row.cover" class="cover-content" fit="cover">
							<div slot="error" class="image-slot">
								<i class="el-icon-picture-outline"></i>
							</div>
						</el-image>
					</template>
				</el-table-column>
				<el-table-column prop="vrResourceName" label="实验名称" align='center' show-overflow-tooltip>
				</el-table-column>
				<el-table-column prop="majorName" label="所属专业" align='center'>
				</el-table-column>
				<el-table-column prop="mode" label="实验模式" align='center'>
					<template slot-scope="scope">
						<span v-for='item in modes' v-if="item.value == scope.row.mode">{{item.label}}</span>
					</template>
				</el-table-column>
				<el-table-column prop="type" label="实验类型" align='center'>
					<template slot-scope="scope">
						<span v-for='item in types' v-if="item.value == scope.row.type">{{item.label}}</span>
					</template>
				</el-table-column>
				<el-table-column prop="state" label="状态" align="center">
					<template slot-scope="scope">
						<el-tag type='success' v-if="scope.row.state == '1'">已启用</el-tag>
						<el-tag type='danger' v-if="scope.row.state == '2'">已禁用</el-tag>
					</template>
				</el-table-column>
				<el-table-column label="操作" align="center" width='350'>
					<template slot-scope="scope">
						<el-button type="info" @click="openState(scope.row)" size="small" v-if="scope.row.state == '1'">禁用</el-button>
						<el-button type="success" @click="openState(scope.row)" size="small" v-if="scope.row.state == '2'">启用</el-button>
						<el-button type="primary" @click="openEdit(scope.row)" size="small" v-if="scope.row.state == '2'">编辑</el-button>
						<el-button type="danger" @click="openDelete(scope.row)" size="small" v-if="scope.row.state == '2'">删除</el-button>
					</template>
				</el-table-column>
			</el-table>
			<div style="margin: 10px; text-align: center;">
				<el-pagination background @current-change="currentChange" :current-page="pageNum" :page-size="pageSize" layout="total, sizes, prev, pager, next, jumper" :total="total">
				</el-pagination>
			</div>
		</div>
		<el-dialog title="添加实验" :show-close="false" :close-on-press-escape='false' :close-on-click-modal='false' :append-to-body='true' :visible.sync="addDialog" width="800px">
			<el-form :model="addForm" :rules="rules" ref="addForm" label-width="110px" style='width: calc(100% - 40px);'>
				<el-form-item label="实验名称" prop="vrResourceName">
					<el-input placeholder="请输入实验名称" v-model="addForm.vrResourceName" maxlength='255' clearable></el-input>
				</el-form-item>
				<el-form-item label="专业" prop="majorId">
					<el-select v-model="addForm.majorId" placeholder="请选择专业" style="width:100%">
						<el-option v-for="item in majors" :key="item.id" :label="item.name" :value="item.id">
						</el-option>
					</el-select>
				</el-form-item>
				<el-form-item label="实验模式" prop="mode">
					<el-select v-model="addForm.mode" placeholder="请选择实验模式" style="width:100%">
						<el-option v-for="item in modes" :key="item.value" :label="item.label" :value="item.value">
						</el-option>
					</el-select>
				</el-form-item>
				<el-form-item label="实验类型" prop="type">
					<el-select v-model="addForm.type" placeholder="请选择实验类型" style="width:100%">
						<el-option v-for="item in types" :key="item.value" :label="item.label" :value="item.value">
						</el-option>
					</el-select>
				</el-form-item>
				<el-form-item label="封面" prop="cover">
					<div class="avataruploads">
						<div class="avatarupcover avatarupcover-add" @click="$refs.icon_add.click()">
							<i class="el-icon-plus"></i>
						</div>
						<img :src="baseurl + addForm.cover" v-if="addForm.cover" />
						<input ref="icon_add" type="file" accept=".jpg, .png, .JPG, .PNG" style="display: none" @change="iconAdd($event)" />
					</div>
				</el-form-item>
				<el-form-item prop="url" label="实验资源">
					<div class="drop-area el-upload-dragger" @click="clickElement($event, 'upload_folder')" @drop="handleFileDrop($event)" @dragleave="stopEvent($event)" @dragenter="stopEvent($event)" @dragover="stopEvent($event)">
						<i class="el-icon-upload"></i>
						<div class="el-upload__text">
							请将资源文件目录拖拽到此处
							<br />
							<em v-if="allFileNum > 0 && allFileNum === upFileNum">已上传</em>
							<em v-if="allFileNum > 0 && allFileNum > upFileNum">正在上传：{{upFileNum}}/{{allFileNum}}</em>
							<em v-if="allFileNum==0" style="color: #F56C6C;">未上传, 请选择目录</em>
							<input ref="upload_folder" webkitdirectory type="file" style="display: none" @change="handleFileInput($event)" />
						</div>
					</div>
					<ul v-if="objects && objects.length" class="el-upload-list el-upload-list--text">
						<li v-for="(object, index) in objects" :key="index" class="el-upload-list__item is-success">
							<a class="el-upload-list__item-name">
								<i class="el-icon-document"></i> {{ object.key }}
							</a>
							<label v-if="!object.uploading" class="el-upload-list__item-status-label"><i class="el-icon-upload-success el-icon-circle-check"></i></label>
							<div v-else role="progressbar" :aria-valuenow="object.progress" aria-valuemin="0" aria-valuemax="100" class="el-progress el-progress--line">
								<div class="el-progress-bar">
									<div class="el-progress-bar__outer" style="height: 2px;">
										<div class="el-progress-bar__inner" :style="`width: ${ object.progress || 0 }%;`"></div>
									</div>
								</div>
								<div class="el-progress__text" style="font-size: 13px;">{{ object.progress || 0 }}%</div>
							</div>
						</li>
					</ul>
				</el-form-item>
			</el-form>
			<div slot="footer" class="dialog-footer">
				<el-button @click="resetAdd" :disabled='dataloading || uploadingAll'>取 消</el-button>
				<el-button type="primary" @click="addData" :disabled='dataloading || uploadingAll'>确 定</el-button>
			</div>
		</el-dialog>
		<el-dialog title="修改实验" :show-close="false" :close-on-press-escape='false' :close-on-click-modal='false' :append-to-body='true' :visible.sync="editDialog" width="800px">
			<el-form :model="editForm" :rules="rules" ref="editForm" label-width="110px" style='width: calc(100% - 40px);'>
				<el-form-item label="实验名称" prop="vrResourceName">
					<el-input placeholder="请输入实验名称" v-model="editForm.vrResourceName" maxlength='255' clearable></el-input>
				</el-form-item>
				<el-form-item label="专业" prop="majorId">
					<el-select v-model="editForm.majorId" placeholder="请选择专业" style="width:100%">
						<el-option v-for="item in majors" :key="item.id" :label="item.name" :value="item.id">
						</el-option>
					</el-select>
				</el-form-item>
				<el-form-item label="实验模式" prop="mode">
					<el-select v-model="editForm.mode" placeholder="请选择实验模式" style="width:100%">
						<el-option v-for="item in modes" :key="item.value" :label="item.label" :value="item.value">
						</el-option>
					</el-select>
				</el-form-item>
				<el-form-item label="实验类型" prop="type">
					<el-select v-model="editForm.type" placeholder="请选择实验类型" style="width:100%">
						<el-option v-for="item in types" :key="item.value" :label="item.label" :value="item.value">
						</el-option>
					</el-select>
				</el-form-item>
				<el-form-item label="封面" prop="cover">
					<div class="avataruploads">
						<div class="avatarupcover avatarupcover-add" @click="$refs.icon_edit.click()">
							<i class="el-icon-plus"></i>
						</div>
						<img :src="baseurl + editForm.cover" v-if="editForm.cover" />
						<input ref="icon_edit" type="file" accept=".jpg, .png, .JPG, .PNG" style="display: none" @change="iconEdit($event)" />
					</div>
				</el-form-item>
				<el-form-item prop="url" label="实验资源">
					<div class="drop-area el-upload-dragger" @click="clickElement($event, 'upload_folder')" @drop="handleFileDrop($event)" @dragleave="stopEvent($event)" @dragenter="stopEvent($event)" @dragover="stopEvent($event)">
						<i class="el-icon-upload"></i>
						<div class="el-upload__text">
							请将资源文件目录拖拽到此处
							<br />
							<em v-if="allFileNum > 0 && allFileNum === upFileNum">已上传</em>
							<em v-if="allFileNum > 0 && allFileNum > upFileNum">正在上传：{{upFileNum}}/{{allFileNum}}</em>
							<div v-if="!allFileNum" v-html="resourceMessage"></div>
							<input ref="upload_folder" webkitdirectory type="file" style="display: none" @change="handleFileInput($event)" />
						</div>
					</div>
					<ul v-if="objects && objects.length" class="el-upload-list el-upload-list--text">
						<li v-for="(object, index) in objects" :key="index" class="el-upload-list__item is-success">
							<a class="el-upload-list__item-name">
								<i class="el-icon-document"></i> {{ object.key }}
							</a>
							<label v-if="!object.uploading" class="el-upload-list__item-status-label"><i class="el-icon-upload-success el-icon-circle-check"></i></label>
							<div v-else role="progressbar" :aria-valuenow="object.progress" aria-valuemin="0" aria-valuemax="100" class="el-progress el-progress--line">
								<div class="el-progress-bar">
									<div class="el-progress-bar__outer" style="height: 2px;">
										<div class="el-progress-bar__inner" :style="`width: ${ object.progress || 0 }%;`"></div>
									</div>
								</div>
								<div class="el-progress__text" style="font-size: 13px;">{{ object.progress || 0 }}%</div>
							</div>
						</li>
					</ul>
				</el-form-item>
			</el-form>
			<div slot="footer" class="dialog-footer">
				<el-button @click="resetEdit" :disabled='dataloading || uploadingAll'>取 消</el-button>
				<el-button type="primary" @click="editData" :disabled='dataloading || uploadingAll'>确 定</el-button>
			</div>
		</el-dialog>
	</div>
</template>

<script>
	import { putProgress, createMultipartUpload, listObjects } from "@/utils/oss.js";
	import { majorList } from '@/api/major.js'
	import { resourceList, resourceSave, resourceUpdate, resourceRemove, resourceUpdateState } from "@/api/vrResource.js"
	export default {
		data() {
			return {
				tableDate: [],
				vrResourceName: "",
				majorId: "",
				mode: "",
				pageNum: 1,
				pageSize: 10,
				total: 0,
				majors: [],
				types: [{
					value: 1,
					label: "平台实验"
				}, {
					value: 2,
					label: "自定义模块实验"
				}],
				modes: [{
					value: 1,
					label: "学习模式"
				}, {
					value: 2,
					label: "考核模式"
				}],
				//上传实验
				objects: [],
				allFileNum: 0,
				upFileNum: 0,
				resourceMessage: "", // 资源上传框提示信息
				uploadingAll:false,
				//diolog
				dataloading: false,
				addDialog: false,
				editDialog: false,
				addForm: {
					majorId: '',
					vrResourceName: '',
					type: '',
					cover: '',
					url: '',
					attachPrefix: '',
					mode: '',
				},
				editForm: {
					vrResourceId: '',
					majorId: '',
					vrResourceName: '',
					type: '',
					cover: '',
					url: '',
					attachPrefix: '',
					mode: '',
				},
				rules: {
					vrResourceName: [{
						required: true,
						message: '请输入实验名称',
						trigger: 'blur'
					}],
					cover: [{
						required: true,
						message: '请上传封面',
						trigger: 'blur'
					}],
					type: [{
						required: true,
						message: '请选择实验类型',
						trigger: 'blur'
					}],
					mode: [{
						required: true,
						message: '请选择实验模式',
						trigger: 'blur'
					}],
					majorId: [{
						required: true,
						message: '请选择专业',
						trigger: 'blur'
					}],
					url: [{
						required: true,
						message: '请上传实验',
						trigger: 'blur'
					}],
				},

			}
		},
		created() {
			this.getMajorList();
			this.getDateList();
		},
		methods: {
			openAdd() {
				this.addDialog = true;
				this.objects = [];
			},
			iconAdd(event) {
				const files = event.target.files;
				if(!files || files.length <= 0) {
					return;
				}
				const file = files[0];
				const key = `szhjxpt/vrResourceCover/${file.name}`;
				putProgress(key, file).then(res => {
					this.addForm.cover = key;
					this.$refs.icon_add.value = '';
				});
			},
			addData() {
				this.dataloading = true;
				setTimeout(_ => {
					this.dataloading = false;
				}, 1000)
				this.$refs.addForm.validate((valid) => {
					if(valid) {
						var data = Object.assign({}, this.addForm);
						resourceSave(data).then(async res => {
							if(res.code == '200') {
								this.$message({
									message: '添加成功',
									type: 'success'
								});
								this.getDateList();
								this.resetAdd();
							} else {
								this.$message({
									message: res.message,
									type: 'error'
								});
							}
						});
					}
				})
			},
			resetAdd() {
				this.addDialog = false;
				this.$refs.addForm.resetFields();
				this.$refs.addForm.clearValidate();
			},
			openEdit(item) {
				this.editDialog = true;
				this.editForm = Object.assign({}, item);
				this.objects = [];
				this.checkOSSResource();
			},
			iconEdit(event) {
				const files = event.target.files;
				if(!files || files.length <= 0) {
					return;
				}
				const file = files[0];
				const key = `szhjxpt/vrResourceCover/${file.name}`;
				putProgress(key, file).then(res => {
					this.editForm = Object.assign({}, this.editForm, {
						cover: key
					});
					this.$refs.icon_edit.value = '';
				});
			},
			editData() {
				this.$refs.editForm.validate((valid) => {
					if(valid) {
						var data = Object.assign({}, this.editForm);
						resourceUpdate(data).then(async res => {
							if(res.code == '200') {
								this.$message({
									message: '编辑成功',
									type: 'success'
								})
								this.getDateList();
								this.resetEdit();
							} else {
								this.$message({
									message: res.message,
									type: 'error'
								})
							}
						})
					}
				})
			},
			resetEdit() {
				this.editDialog = false;
				this.$refs.editForm.resetFields();
				this.$refs.editForm.clearValidate()
			},
			openDelete(item) {
				this.$confirm('是否删除该实验?', '提示', {
					confirmButtonText: '确定',
					cancelButtonText: '取消',
					type: 'warning'
				}).then(() => {
					resourceRemove({
						vrResourceId: item.vrResourceId
					}).then(async res => {
						if(res.code == '200') {
							this.$message({
								message: '删除成功',
								type: 'success'
							})
							this.getDateList();
						} else {
							this.$message({
								message: res.message,
								type: 'error'
							})
						}
					})
				}).catch(() => {});
			},
			openState(item) {
				var message = item.state == '1' ? '是否禁用该实验?' : '是否启用该实验?';
				this.$confirm(message, '提示', {
					confirmButtonText: '确定',
					cancelButtonText: '取消',
					type: 'warning'
				}).then(() => {
					resourceUpdateState({
						vrResourceId: item.vrResourceId,
						state: item.state == '1' ? '2' : '1',
					}).then(async res => {
						if(res.code == '200') {
							this.$message({
								message: res.message,
								type: 'success'
							});
							this.getDateList();
						} else {
							this.$message({
								message: res.message,
								type: 'error'
							});
						}
					})
				}).catch(() => {});
			},
			getMajorList() {
				majorList({}).then(res => {
					this.majors = res.data || []
				})
			},
			currentChange(pageNum) {
				this.pageNum = pageNum;
				this.getDateList()
			},
			getDateList() {
				var data = {
					pageNum: this.pageNum,
					pageSize: this.pageSize,
					vrResourceName: this.vrResourceName ? this.vrResourceName : null,
					majorId: this.majorId ? this.majorId : null,
					mode: this.mode ? this.mode : null,
				}
				resourceList(data).then(async res => {
					this.tableDate = res.data.list;
					this.total = res.data.total;
				});
			},
			setValue(url, attachPrefix) {
				if(this.addDialog) {
					this.addForm.url = url;
					this.addForm.attachPrefix = attachPrefix;
				}
				if(this.editDialog) {
					this.editForm.url = url;
					this.editForm.attachPrefix = attachPrefix;
				}
			},
			/**
			 * json文件是否上传
			 */
			checkSuccess() {
				this.allFileNum = this.objects.length;
				this.upFileNum = this.objects.filter(item => item.uploading === false).length;
				if(this.allFileNum == this.upFileNum) {
					this.uploadingAll = false;
					this.$refs["upload_folder"].value = ''
				}
			},
			/**
			 * 资源文件上传
			 * @param {File} file 本地文件
			 * @param {String} relativePath 文件相对路径
			 */
			handleResourceUpload(file, relativePath) {
				const that = this;
				const key = `szhjxpt/vrResource/${relativePath}`;
				// 检查重复上传
				let index = this.objects.findIndex(item => item.key === key);
				if(index > -1) {
					this.objects[index].file = file;
					return;
				}
				this.uploadingAll = true;
				// 上传
				this.objects.push({
					key: key,
					file: file,
					uploading: true
				});
				createMultipartUpload(key, file, this.multiUploadProgress).then(({
					name,
					res
				}) => {
					const target = that.objects.find(object => object.key === key);
					target.uploading = false;
					// 更新lock状态
					that.checkSuccess()
					// 通过任一 url 截取资源文件父目录, 通过 json 文件地址截取资源名称
					// url: http://zf-vr.oss-cn-hangzhou.aliyuncs.com/szhjxpt/vrResource/MRWebGl/Build/MRWebGl.json
					const durl = /https?:\/\/[\w.:\-_%]*\/[\w.\-_%]*\/[\w.\-_%]*\/[\w.\-_%]*\/[\w.\-_%]*\//i;
					const jurl = /[\w.:\-_\/%]*\/Build\/[\w.\-_%]*.json/i;
					if(res && res.requestUrls && res.requestUrls.length > 0) {
						//只保留vrAdmin到Build这一段
						var allUrls = res.requestUrls[0].match(durl);
						if(allUrls) {
							var allUrl = allUrls[0];
							var url = 'szhjxpt' + allUrl.split('szhjxpt')[1];
							if(name && name.match(jurl)) {
								var node = res.requestUrls[0].split("/");
								var attachPrefix = node[node.length - 1].replace(".json", "");
								that.setValue(url, attachPrefix)
							}
						}
					}
				})
			},
			/**
			 * 分片上传进度
			 * @param {Number} progress 分片上传进度, 取值范围: 0~1
			 * @param {Object} checkpoint 本地分片上传结果
			 */
			multiUploadProgress(progress, checkpoint) {
				if(!checkpoint) {
					return;
				}
				const target = this.objects.find(item => item.key === checkpoint.name);
				this.$set(target, "checkpoint", checkpoint);
				this.$set(target, "progress", Math.round(progress * 100));
			},
			/**
			 * 点击上传文件 / 目录
			 */
			handleFileInput(event) {
				const that = this
				for(const file of event.target.files) {
					that.handleResourceUpload(file, file.webkitRelativePath || file.name)
				}
			},
			/**
			 * 拖拽上传文件 / 目录
			 */
			handleFileDrop(event) {
				this.stopEvent(event);
				const items = event.dataTransfer.items;
				if(!items.length || items[0].kind !== "file") return;
				for(const item of items) {
					const entry = item.webkitGetAsEntry();
					this.loadChildFiles(entry, entry.name);
				}
			},
			/**
			 * 递归获取文件
			 * @param {FileSystemEntry|FileSystemDirectoryEntry} entry 文件 / 目录
			 * @param {String} relativePath 文件/目录相对路径
			 */
			loadChildFiles(entry, relativePath) {
				const that = this;
				if(entry.isFile) {
					entry.file(file => that.handleResourceUpload(file, relativePath));
					return;
				}
				const reader = entry.createReader();
				reader.readEntries(entries =>
					entries.forEach(entry =>
						that.loadChildFiles(
							entry,
							`${relativePath ? relativePath : ""}/${entry.name}`
						)
					)
				);
			},
			async checkOSSResource() {
				// 验证 OSS 文件目录存在
				const {
					res
				} = await listObjects(this.editForm.url)
				this.resourceMessage = res.requestUrls && res.requestUrls.length ?
					`<em style="color: #67C23A">资源已上传到服务器</em>` :
					`<em style="color: #F56C6C">资源已被删除, 需重新上传</em>`
			},
			/**
			 * 阻止浏览器默认操作
			 */
			stopEvent(event) {
				event.stopPropagation();
				event.preventDefault();
			},
			/**
			 * 模拟点击
			 */
			clickElement(event, el) {
				event.stopPropagation();
				this.$refs[el].click();
			},
		}
	}
</script>
<style lang="scss" scoped>
	.el-upload-dragger {
		width: 100%;
	}
	
	.el-upload--text {
		width: 100%;
		height: 100px;
	}
	
	.el-upload-list {
		overflow: auto;
		width: 100%;
		height: 100px;
		margin: 5px 0;
	}
	
	.upload-content {
		width: 100%;
		height: 100px;
		display: block;
	}
</style>